import 'package:built_collection/built_collection.dart';
import 'package:website.core/core/domain/entities/money_amount.dart';
import 'package:website.core/core/domain/helpers/add_spaces_to_price/add_spaces_to_price.dart';

const _kPrettifiablePriceCurrencies = {
  'RUB',
  'USD',
  'EUR',
};

abstract class PrettifyWebPurchaseItemPrices {
  BuiltList<String> call({
    required BuiltList<MoneyAmount> prices,
  });
}

class PrettifyWebPurchaseItemPricesImpl implements PrettifyWebPurchaseItemPrices {
  const PrettifyWebPurchaseItemPricesImpl({
    required AddSpacesToPrice addSpacesToPrice,
  }) : _addSpacesToPrice = addSpacesToPrice;

  final AddSpacesToPrice _addSpacesToPrice;

  @override
  BuiltList<String> call({
    required BuiltList<MoneyAmount> prices,
  }) {
    var pricesPrettifiable = true;

    final prettifiablePriceRegExp = RegExp(r'^[0-9]+(\.[0-9]+)?$');

    for (final price in prices) {
      pricesPrettifiable &= _kPrettifiablePriceCurrencies.contains(price.currency);
      pricesPrettifiable &= prettifiablePriceRegExp.hasMatch(price.value);
    }

    if (!pricesPrettifiable) {
      throw const FormatException();
    }

    var maxSignificantDigitAfterCommaCount = -1;

    for (final price in prices) {
      final priceParts = price.value.split('.');

      int significantDigitAfterCommaCount;

      if (priceParts.length == 1) {
        significantDigitAfterCommaCount = 0;
      } else {
        significantDigitAfterCommaCount = priceParts.last.length;

        for (var i = priceParts.last.length - 1; i >= 0; i--) {
          if (priceParts.last[i] == '0') {
            significantDigitAfterCommaCount--;
          }
        }
      }

      if (maxSignificantDigitAfterCommaCount < significantDigitAfterCommaCount) {
        maxSignificantDigitAfterCommaCount = significantDigitAfterCommaCount;
      }
    }

    final digitAfterCommaCount =
        maxSignificantDigitAfterCommaCount == 1 ? 2 : maxSignificantDigitAfterCommaCount;

    final pretifiedPrices = <String>[];

    for (final price in prices) {
      final priceWithSpaces = _addSpacesToPrice(
        price: price.value,
        delimiter: '.',
      );

      final priceParts = priceWithSpaces.split('.');

      if (digitAfterCommaCount == 0) {
        pretifiedPrices.add(priceParts.first);
      } else {
        var updatedPriceLastPart = '';

        for (var i = 0; i < digitAfterCommaCount; i++) {
          if (priceParts.length == 1 || i > priceParts.last.length - 1) {
            updatedPriceLastPart += '0';
          } else {
            updatedPriceLastPart += priceParts.last[i];
          }
        }

        pretifiedPrices.add('${priceParts.first},$updatedPriceLastPart');
      }
    }

    return pretifiedPrices.build();
  }
}
